<template>
    <div class="container">
        <canvas ref="gameCanvas" class="game-canvas"></canvas>
        <div class="next-shape">
            <canvas ref="nextShapeCanvas" class="next-shape-canvas"></canvas>
        </div>
        <div class="controls">
            <button @click="moveLeft">左移</button>
            <button @click="rotate">旋转</button>
            <button @click="moveRight">右移</button>
            <button @click="moveDown">下移</button>
        </div>
        <div v-if="isGameOver" class="game-over">游戏结束</div>
    </div>
</template>
<script>
export default {
    data() {
        return {
            isGameOver: false,
            currentShape: null,
            nextShape: null,
            grid: [],
            context: null,
            nextShapeContext: null,
            shadowShape: null,
        };
    },
    mounted() {
        this.context = this.$refs.gameCanvas.getContext("2d");
        this.nextShapeContext = this.$refs.nextShapeCanvas.getContext("2d");
        this.initGame();
    },
    methods: {
        initGame() {
            this.grid = Array(20)
                .fill(null)
                .map(() => Array(10).fill(0));
            this.currentShape = this.createShape();
            this.nextShape = this.createShape();
            this.shadowShape = this.createShadowShape();
            this.drawGrid();
            this.drawCurrentShape();
            this.drawNextShape();
            this.drawShadowShape();
        },
        createShape() {
            // 创建一个新的方块
            const shapes = [
                [
                    [1, 1],
                    [1, 1],
                ], // 方块
                [
                    [0, 1, 0],
                    [1, 1, 1],
                ], // T 形
                [
                    [1, 0],
                    [1, 0],
                    [1, 1],
                ], // L 形
                [
                    [0, 1],
                    [0, 1],
                    [1, 1],
                ], // 反 L 形
                [[1, 1, 1, 1]], // I 形
                [
                    [1, 1, 0],
                    [0, 1, 1],
                ], // S 形
                [
                    [0, 1, 1],
                    [1, 1, 0],
                ], // Z 形
            ];
            const shape = shapes[Math.floor(Math.random() * shapes.length)];
            return { shape, x: 4, y: 0 };
        },
        createShadowShape() {
            // 创建一个影子方块
            const shadowShape = JSON.parse(JSON.stringify(this.currentShape));
            while (this.canMove(shadowShape, 0, 1)) {
                shadowShape.y += 1;
            }
            return shadowShape;
        },
        canMove(shape, offsetX, offsetY) {
            for (let y = 0; y < shape.shape.length; y++) {
                for (let x = 0; x < shape.shape[y].length; x++) {
                    if (shape.shape[y][x]) {
                        const newX = shape.x + x + offsetX;
                        const newY = shape.y + y + offsetY;
                        if (newX < 0 || newX >= 10 || newY >= 20 || (this.grid[newY] && this.grid[newY][newX])) {
                            return false;
                        }
                    }
                }
            }
            return true;
        },
        drawGrid() {
            this.context.clearRect(0, 0, this.$refs.gameCanvas.width, this.$refs.gameCanvas.height);
            for (let y = 0; y < 20; y++) {
                for (let x = 0; x < 10; x++) {
                    if (this.grid[y][x]) {
                        this.context.fillStyle = "blue";
                        this.context.fillRect(x * 30, y * 30, 30, 30);
                    }
                }
            }
        },
        drawCurrentShape() {
            this.context.fillStyle = "red";
            for (let y = 0; y < this.currentShape.shape.length; y++) {
                for (let x = 0; x < this.currentShape.shape[y].length; x++) {
                    if (this.currentShape.shape[y][x]) {
                        this.context.fillRect((this.currentShape.x + x) * 30, (this.currentShape.y + y) * 30, 30, 30);
                    }
                }
            }
        },
        drawShadowShape() {
            this.context.fillStyle = "rgba(255, 0, 0, 0.5)";
            for (let y = 0; y < this.shadowShape.shape.length; y++) {
                for (let x = 0; x < this.shadowShape.shape[y].length; x++) {
                    if (this.shadowShape.shape[y][x]) {
                        this.context.fillRect((this.shadowShape.x + x) * 30, (this.shadowShape.y + y) * 30, 30, 30);
                    }
                }
            }
        },
        drawNextShape() {
            this.nextShapeContext.clearRect(0, 0, this.$refs.nextShapeCanvas.width, this.$refs.nextShapeCanvas.height);
            this.nextShapeContext.fillStyle = "red";
            for (let y = 0; y < this.nextShape.shape.length; y++) {
                for (let x = 0; x < this.nextShape.shape[y].length; x++) {
                    if (this.nextShape.shape[y][x]) {
                        this.nextShapeContext.fillRect(x * 30, y * 30, 30, 30);
                    }
                }
            }
        },
        moveLeft() {
            if (this.canMove(this.currentShape, -1, 0)) {
                this.currentShape.x -= 1;
                this.updateShadowShape();
                this.drawGrid();
                this.drawCurrentShape();
                this.drawShadowShape();
            }
        },
        moveRight() {
            if (this.canMove(this.currentShape, 1, 0)) {
                this.currentShape.x += 1;
                this.updateShadowShape();
                this.drawGrid();
                this.drawCurrentShape();
                this.drawShadowShape();
            }
        },
        moveDown() {
            if (this.canMove(this.currentShape, 0, 1)) {
                this.currentShape.y += 1;
                this.updateShadowShape();
                this.drawGrid();
                this.drawCurrentShape();
                this.drawShadowShape();
            } else {
                this.lockShape();
                this.checkLines();
                this.currentShape = this.nextShape;
                this.nextShape = this.createShape();
                this.shadowShape = this.createShadowShape();
                this.drawGrid();
                this.drawCurrentShape();
                this.drawNextShape();
                this.drawShadowShape();
                if (!this.canMove(this.currentShape, 0, 0)) {
                    this.isGameOver = true;
                }
            }
        },
        rotate() {
            const newShape = this.rotateShape(this.currentShape.shape);
            const testShape = { ...this.currentShape, shape: newShape };
            if (this.canMove(testShape, 0, 0)) {
                this.currentShape.shape = newShape;
                this.updateShadowShape();
                this.drawGrid();
                this.drawCurrentShape();
                this.drawShadowShape();
            }
        },
        rotateShape(shape) {
            const newShape = [];
            for (let x = 0; x < shape[0].length; x++) {
                newShape[x] = [];
                for (let y = 0; y < shape.length; y++) {
                    newShape[x][y] = shape[shape.length - y - 1][x];
                }
            }
            return newShape;
        },
        lockShape() {
            for (let y = 0; y < this.currentShape.shape.length; y++) {
                for (let x = 0; x < this.currentShape.shape[y].length; x++) {
                    if (this.currentShape.shape[y][x]) {
                        this.grid[this.currentShape.y + y][this.currentShape.x + x] = 1;
                    }
                }
            }
        },
        checkLines() {
            for (let y = 19; y >= 0; y--) {
                if (this.grid[y].every((cell) => cell === 1)) {
                    this.grid.splice(y, 1);
                    this.grid.unshift(Array(10).fill(0));
                }
            }
        },
        updateShadowShape() {
            this.shadowShape = this.createShadowShape();
        },
    },
};
</script>
<style>
.container {
    position: relative;
    width: 300px;
    height: 600px;
    margin: 0 auto;
}

.game-canvas {
    width: 300px;
    height: 600px;
    background-color: #000;
    border: 2px solid #fff;
}

.game-over {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    color: white;
    font-size: 24px;
    text-align: center;
    z-index: 10;
}

.controls {
    display: flex;
    justify-content: space-around;
    margin-top: 10px;
}

.next-shape {
    position: absolute;
    top: 10px;
    right: 10px;
    width: 120px;
    height: 120px;
    background-color: #000;
    border: 2px solid #fff;
    padding: 5px;
}

.next-shape-canvas {
    width: 100%;
    height: 100%;
}

/* 新增的影子方块样式 */
.shadow-shape {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    pointer-events: none; /* 防止影子方块影响点击事件 */
}
</style>
